package fun.werfamily.wf.user.core.domain.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import fun.werfamily.wf.base.exception.BaseCoreException;
import fun.werfamily.wf.user.core.domain.constant.RedisConstant;
import fun.werfamily.wf.user.core.domain.dto.resp.UserAddressDTO;
import fun.werfamily.wf.user.core.domain.dto.resp.UserAddressIdDTO;
import fun.werfamily.wf.user.core.domain.enums.ResponseCodeEnum;
import fun.werfamily.wf.user.core.domain.service.IUserAddressService;
import fun.werfamily.wf.user.core.infrastructure.dataobject.UserAddressDO;
import fun.werfamily.wf.user.core.infrastructure.mapper.UserAddressMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class IUserAddressServiceImpl extends ServiceImpl<UserAddressMapper, UserAddressDO> implements IUserAddressService {

    /**
     * 用户收货地址列表
     *
     * @param userCode
     * @return
     */
    @Override
    @Cacheable(cacheNames = RedisConstant.USER_ADDRESS_LIST, key = "#root.args[0]", unless = "#result == null")
    public List<UserAddressDTO> listByUserId(String userCode) {
        // 查询数据库
        List<UserAddressDTO> userAddressDTOList = new ArrayList<>();
        QueryWrapper<UserAddressDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserAddressDO::getUserCode, userCode);
        queryWrapper.orderByDesc("is_default, id");
        queryWrapper.last("limit 10");
        List<UserAddressDO> userAddressDOList = list(queryWrapper);
        if (CollectionUtils.isNotEmpty(userAddressDOList)) {
            for (UserAddressDO userAddressDO : userAddressDOList) {
                UserAddressDTO userAddressDTO = new UserAddressDTO();
                BeanUtils.copyProperties(userAddressDO, userAddressDTO);
                userAddressDTO.setAddressId(userAddressDO.getId());
                userAddressDTOList.add(userAddressDTO);
            }
        }
        return userAddressDTOList;
    }

    @Override
    public UserAddressDTO getDetailById(UserAddressIdDTO userAddressIdDTO) {
        QueryWrapper<UserAddressDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserAddressDO::getIsDeleted, Boolean.FALSE);
        queryWrapper.lambda().eq(UserAddressDO::getId, userAddressIdDTO.getAddressId());
        UserAddressDO record = getOne(queryWrapper);
        if (null == record) {
            throw new BaseCoreException(ResponseCodeEnum.DATA_IS_NOT_EXISTS);
        }
        UserAddressDTO userAddressDTO = new UserAddressDTO();
        BeanUtils.copyProperties(record, userAddressDTO);
        userAddressDTO.setAddressId(record.getId());
        return userAddressDTO;
    }

    /**
     * 保存收货地址
     *
     * @param userAddressDTO
     * @return
     */
    @Override
    @CacheEvict(cacheNames = {RedisConstant.USER_ADDRESS_LIST,RedisConstant.USER_DEFAULT_ADDRESS}, key = "#root.args[0].userCode")
    public Boolean saveAddress(UserAddressDTO userAddressDTO) {
        UserAddressDO userAddressDO = new UserAddressDO();
        BeanUtils.copyProperties(userAddressDTO, userAddressDO);

        userAddressDO.setCreateBy(String.valueOf(userAddressDTO.getUserCode()));
        userAddressDO.setUpdateBy(String.valueOf(userAddressDTO.getUserCode()));
        QueryWrapper<UserAddressDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserAddressDO::getUserCode, userAddressDTO.getUserCode());
        List<UserAddressDO> userAddressDOList = list(queryWrapper);
        if (CollectionUtils.isEmpty(userAddressDOList)) {
            userAddressDO.setIsDefault(Boolean.TRUE);
        }
        // 更新默认收获地址
        if (userAddressDTO.getIsDefault() && CollectionUtils.isNotEmpty(userAddressDOList)) {
            QueryWrapper<UserAddressDO> queryWrapperDefault = new QueryWrapper<>();
            queryWrapperDefault.lambda().eq(UserAddressDO::getIsDefault, Boolean.TRUE);
            queryWrapperDefault.lambda().eq(UserAddressDO::getUserCode, userAddressDTO.getUserCode());
            UserAddressDO defaultAddress = getOne(queryWrapperDefault);
            if (null != defaultAddress) {
                defaultAddress.setIsDefault(Boolean.FALSE);
                updateById(defaultAddress);
            }
        }
        // 保存地址
        return save(userAddressDO);
    }

    /**
     * 更新收货地址
     *
     * @param userAddressDTO
     * @return
     */
    @Override
    @CacheEvict(cacheNames = {RedisConstant.USER_ADDRESS_LIST,RedisConstant.USER_DEFAULT_ADDRESS}, key = "#root.args[0].userCode")
    public Boolean updateAddress(UserAddressDTO userAddressDTO) {
        List<UserAddressDO> userAddressDOS = new ArrayList<>();
        UserAddressDO record = getById(userAddressDTO.getAddressId());
        if (null == record) {
            throw new BaseCoreException(ResponseCodeEnum.DATA_IS_NOT_EXISTS);
        }
        BeanUtils.copyProperties(userAddressDTO, record);
        QueryWrapper<UserAddressDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserAddressDO::getIsDefault, Boolean.TRUE);
        queryWrapper.lambda().eq(UserAddressDO::getUserCode, userAddressDTO.getUserCode());
        UserAddressDO defaultAddress = getOne(queryWrapper);
        if (null != defaultAddress) {
            defaultAddress.setIsDefault(Boolean.FALSE);
            userAddressDOS.add(defaultAddress);
        }
        record.setIsDefault(Boolean.TRUE);
        record.setUpdateBy(String.valueOf(userAddressDTO.getUserCode()));
        userAddressDOS.add(record);
        return updateBatchById(userAddressDOS);
    }

    /**
     * 删除收货地址
     *
     * @param userAddressIdDTO
     * @return
     */
    @Override
    @CacheEvict(cacheNames = {RedisConstant.USER_ADDRESS_LIST,RedisConstant.USER_DEFAULT_ADDRESS}, key = "#root.args[0].userCode")
    public Boolean deleteAddress(UserAddressIdDTO userAddressIdDTO) {
        if (null == userAddressIdDTO.getAddressId()) {
            throw new BaseCoreException(ResponseCodeEnum.DATA_IS_NOT_EXISTS);
        }
        UserAddressDO record = getById(userAddressIdDTO.getAddressId());
        if (null == record) {
            throw new BaseCoreException(ResponseCodeEnum.DATA_IS_NOT_EXISTS);
        }
        record.setIsDeleted(true);
        record.setUpdateBy(String.valueOf(userAddressIdDTO.getUserCode()));
        return updateById(record);
    }

    /**
     * 设置默认收货地址
     *
     * @param userAddressIdDTO
     * @return
     */
    @Override
    @CacheEvict(cacheNames = {RedisConstant.USER_ADDRESS_LIST,RedisConstant.USER_DEFAULT_ADDRESS}, key = "#root.args[0].userCode")
    public Boolean setDefault(UserAddressIdDTO userAddressIdDTO) {
        Long addressId = userAddressIdDTO.getAddressId();
        List<UserAddressDO> userAddressDOS = new ArrayList<>();
        if (null == addressId) {
            throw new BaseCoreException(ResponseCodeEnum.DATA_IS_NOT_EXISTS);
        }
        UserAddressDO record = getById(addressId);
        if (null == record) {
            throw new BaseCoreException(ResponseCodeEnum.DATA_IS_NOT_EXISTS);
        }
        QueryWrapper<UserAddressDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserAddressDO::getIsDefault, Boolean.TRUE);
        queryWrapper.lambda().eq(UserAddressDO::getUserCode, userAddressIdDTO.getUserCode());
        UserAddressDO defaultAddress = getOne(queryWrapper);
        if (null != defaultAddress) {
            defaultAddress.setIsDefault(Boolean.FALSE);
            userAddressDOS.add(defaultAddress);
        }
        record.setIsDefault(true);
        record.setUpdateBy(String.valueOf(userAddressIdDTO.getUserCode()));
        userAddressDOS.add(record);
        return updateBatchById(userAddressDOS);
    }

    @Cacheable(cacheNames = RedisConstant.USER_DEFAULT_ADDRESS, key = "#root.args[0]", unless = "#result == null")
    @Override
    public UserAddressDTO getDefault(String userCode) {
        UserAddressDTO userAddressDTO = new UserAddressDTO();
        QueryWrapper<UserAddressDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserAddressDO::getUserCode, userCode);
        queryWrapper.lambda().eq(UserAddressDO::getIsDefault, Boolean.TRUE);
        queryWrapper.lambda().eq(UserAddressDO::getIsDeleted, Boolean.FALSE);
        UserAddressDO defaultAddress = getOne(queryWrapper);
        if (null == defaultAddress) {
            return null;
        }
        BeanUtils.copyProperties(defaultAddress, userAddressDTO);
        userAddressDTO.setAddressId(defaultAddress.getId());
        return userAddressDTO;
    }
}
